<script>on mouseUplock screenshow card field "Version"unlock screen with dissolveend mouseUp</script>
</part>
<part>
<id>8</id>
<type>button</type>
<visible> <true /> </visible>
<reserved5> 0 </reserved5>
<reserved4> 0 </reserved4>
<reserved3> 0 </reserved3>
<reserved2> 0 </reserved2>
<reserved1> 0 </reserved1>
<enabled> <true /> </enabled>
<rect>
<left>0</left>
<top>264</top>
<right>46</right>
<bottom>342</bottom>
</rect>
<style>transparent</style>
<showName> <false /> </showName>
<highlight> <true /> </highlight>
<autoHighlight> <false /> </autoHighlight>
<sharedHighlight> <true /> </sharedHighlight>
<family>0</family>
<titleWidth>0</titleWidth>
<icon>11045</icon>
<textAlign>center</textAlign>
<font>Chicago</font>
<textSize>12</textSize>
<textStyle>plain</textStyle>
<name>Home</name>
<script>on mouseUpif the stacks contains "Home"and number of lines of the stacks > 1 thendoMenu "Close Stack"end ifvisual scroll upgo homeend mouseUp</script>
</part>
<part>
<id>7</id>
<type>field</type>
<visible> <false /> </visible>
<dontWrap> <false /> </dontWrap>
<dontSearch> <false /> </dontSearch>
<sharedText> <false /> </sharedText>
<fixedLineHeight> <true /> </fixedLineHeight>
<autoTab> <false /> </autoTab>
<lockText> <true /> </lockText>
<rect>
<left>211</left>
<top>206</top>
<right>432</right>
<bottom>273</bottom>
</rect>
<style>opaque</style>
<autoSelect> <false /> </autoSelect>
<showLines> <false /> </showLines>
<wideMargins> <true /> </wideMargins>
<multipleLines> <false /> </multipleLines>
<reservedFamily> 0 </reservedFamily>
<titleWidth>0</titleWidth>
<icon>0</icon>
<textAlign>center</textAlign>
<font>Geneva</font>
<textSize>9</textSize>
<textStyle>plain</textStyle>
<textHeight>12</textHeight>
<name>Version</name>
<script>on mouseUplock screenhide meunlock screen with dissolveend mouseUp</script>
</part>
<content>
<layer>background</layer>
<id>3</id>
<text>This is a version of a fairly common XFCN called HPopupMenu which, surprisingly enough, creates a hierarchical popup menu anywhere on a card. This version is much more robust than other versions I have seen and incorporates some features that I have not seen in other implementations, which is why I wrote it.Feel free to send questions, comments, praise and money to me:Jon Pugh(408) 862-7094jpugh@apple.comApplelink: JONPUGHThis stack, the source code, and the XCMDs and XFCNs contained herein are copyright 1989 through 1993 by Jon Pugh. They may be used freely as long as no money is charged for them or any product that contains them.Feel free to contact me for a licence to use this in commercial stacks.</text>
</content>
<content>
<layer>card</layer>
<id>7</id>
<text>Made it so you canΓÇÖt select disabled menu items. I guess not many people disable popup menu items. I also bulletproofed some of the error routines, fixed the 300 submenu limitation check and sped up simple popups.</text>
</content>
<name></name>
<script>on closeCardif visible of card field "Version" then hide card field "Version"pass closeCardend closeCard</script>
</card>
card_4578.xml
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE card PUBLIC "-//Apple, Inc.//DTD card V 2.0//EN" "" >
<text>get HPopupMenu ( MenuItems, CheckedItem, Top, Left [, Font, Size] )ΓÇó MenuItems is either a MENU resource id number or a string of comma, return, or semicolon delimited words like so:Main1,Sub1,Sub2,Sub3;Main2,Sub1,Sub2,Sub3;Main3;Main4,Sub1,Sub2The itemDelimiter (comma) separates main menu items from submenu items while a return or semicolon separates the main menu items. When there are no submenus can you use all itemDelimters, returns, or semicolons.ΓÇó CheckedItem is the number of the desired default menu item. If it is zero then the menu drops down, while if it is negative then there is no check mark but the default item is the absolute value of CheckedItem.ΓÇó Top, Left is where the menu should appear. These coordinates are local Hypercard coordinates.ΓÇó The Font and Size are optional parameters which control the menu text. If they are not specified then the System font will be used.The returned result will be:main menu item, sub menu item, main menu number, sub menu number</text>
</content>
<name></name>
<script></script>
</card>
card_6129.xml
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE card PUBLIC "-//Apple, Inc.//DTD card V 2.0//EN" "" >
<text>ΓÇó The location of the menu takes into account the card windowΓÇÖs location so that the menu pops up in the right place even on large screens.ΓÇó You can use this as either a regular popup menu or a hierarchical one.ΓÇó You may have a very large number of menu items in either the main menu or any of the submenus. The only limitation is that you can only have 300 hierarchical menus.ΓÇó You can use the itemDelimiter (a comma), returns, or semicolons for regular popup menus or the itemDelimiter to seperate hierarchical menu items and semicolons or returns to seperate the main menu items. When the itemDelimter is undefined (prior to Hypercard 2.1) it is a comma.ΓÇó You can make the menu drop down, pop up at a certain item, and/or have a default checked item through the use of the checkedItem parameter.ΓÇó You can select the main menu item even if there is a sub menu on it.</text>
</content>
<name></name>
<script></script>
</card>
card_7757.xml
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE card PUBLIC "-//Apple, Inc.//DTD card V 2.0//EN" "" >
<text>• You can set the menu’s font and size to anything that you wish, allowing you to make small menus, like Geneva 9.• You can use all the standard meta-characters for making special menu items. Bold, Italic, Shadow, icons, marked items all work. You can even use color icons (cicn resources)! See the examples.• You can put small black and white icons (SICN resources) on menu items with my custom † metacharacter.• You can use all the metacharacters in menus if they are not being used for their special meanings. You can also use commas by changing the itemDelimiter property (Hypercard 2.1 or greater only).• You can add a menu item of "®TYPE" to get all the resources of that type added to the menu in that item’s place.• You can use MENU resources instead of a string. These resources may be connected arbitrarily deeply to create submenus deeper than one level.</text>
</content>
<name></name>
<script></script>
</card>
card_4787.xml
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE card PUBLIC "-//Apple, Inc.//DTD card V 2.0//EN" "" >
<script>on mouseDownset hilite of me to trueput "One,Two,Three,Four,Five,Six,Seven,Eight,Nine,Ten" into choices-- find out what number the button isput 0 into lastItemrepeat with i = 1 to number of items of choicesif item i of choices = short name of me thenput i into lastItemexit repeatend ifend repeat-- lastItem is negative so that there is no check markget HPopUpMenu(choices, -lastItem, top of me+1, left of me)set hilite of me to false-- check for errorsif the result is not empty then put the resultif item 1 of it is not empty thenput item 1 of it into lastItem -- returned item nameset the name of the target to lastItem -- change button nameend ifend mouseDown</script>
</part>
<part>
<id>3</id>
<type>button</type>
<visible> <true /> </visible>
<reserved5> 0 </reserved5>
<reserved4> 0 </reserved4>
<reserved3> 0 </reserved3>
<reserved2> 0 </reserved2>
<reserved1> 0 </reserved1>
<enabled> <true /> </enabled>
<rect>
<left>102</left>
<top>78</top>
<right>177</right>
<bottom>98</bottom>
</rect>
<style>roundrect</style>
<showName> <true /> </showName>
<highlight> <false /> </highlight>
<autoHighlight> <false /> </autoHighlight>
<sharedHighlight> <true /> </sharedHighlight>
<family>0</family>
<titleWidth>0</titleWidth>
<icon>0</icon>
<textAlign>center</textAlign>
<font>Chicago</font>
<textSize>12</textSize>
<textStyle>plain</textStyle>
<name>See Script</name>
<script>on mouseUpedit script of button 1end mouseUp</script>
</part>
<part>
<id>9</id>
<type>button</type>
<visible> <true /> </visible>
<reserved5> 0 </reserved5>
<reserved4> 0 </reserved4>
<reserved3> 0 </reserved3>
<reserved2> 0 </reserved2>
<reserved1> 0 </reserved1>
<enabled> <true /> </enabled>
<rect>
<left>291</left>
<top>82</top>
<right>310</right>
<bottom>94</bottom>
</rect>
<style>transparent</style>
<showName> <false /> </showName>
<highlight> <false /> </highlight>
<autoHighlight> <false /> </autoHighlight>
<sharedHighlight> <true /> </sharedHighlight>
<family>0</family>
<titleWidth>0</titleWidth>
<icon>11893</icon>
<textAlign>center</textAlign>
<font>Chicago</font>
<textSize>12</textSize>
<textStyle>plain</textStyle>
<name></name>
<script>on mouseDownsend mouseDown to hittest(the mouseLoc, "btn")end mouseDown</script>
</part>
<content>
<layer>background</layer>
<id>3</id>
<text><span class="style5">egular Popup Menus!</span><span class="style1">In this example we see how the HPopupMenu command can function as a completely normal popup menu. This is the simplest way to use this XFCN.The menu item string is seperated by commas. These are all transformed into semicolons when the XFCN sees that there are no heirarchical menus being used. Semicolons could be used also, but commas give us the ability to say "item N of choices" and use HypercardΓÇÖs limited array capabilities. The commas are the default itemDelimiter and can be changed if you want.You may also use returns to seperate items so that you can use the Hypercard syntax "line N of choices". This is just more flexibility.In Hypercard 2.x you can set the itemDelimiter property to ";" and use the semicolons that the menu manager uses. This spares the XFCN from having to change the commas or returns to semicolons, but this shouldnΓÇÖt be a problem since this is a pretty quick operation.</span></text>
</content>
<name></name>
<script></script>
</card>
card_7239.xml
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE card PUBLIC "-//Apple, Inc.//DTD card V 2.0//EN" "" >
<script>on mouseDownglobal hasColorQDif xor(the optionKey is down, hasColorQD)then put "Macintosh^1,Application^2,File^3,Folder^4,Disk^5" into choiceselse put "MacintoshΓÇá6,ApplicationΓÇá7,FileΓÇá8,FolderΓÇá9,DiskΓÇá:" into choices-- find out what number the button isput 0 into lastItemrepeat with i = 1 to number of items of choicesif item i of choices contains short name of me thenput i into lastItemexit repeatend ifend repeat-- lastItem is negative so that there is no check markget HPopUpMenu(choices, -lastItem, top of me+1, left of me)-- check for errorsif the result is not empty then put the resultif item 1 of it is not empty thenput item 1 of it into lastItem -- returned item nameset the name of the target to lastItem -- change button nameend ifend mouseDown</script>
</part>
<part>
<id>2</id>
<type>button</type>
<visible> <true /> </visible>
<reserved5> 0 </reserved5>
<reserved4> 0 </reserved4>
<reserved3> 0 </reserved3>
<reserved2> 0 </reserved2>
<reserved1> 0 </reserved1>
<enabled> <true /> </enabled>
<rect>
<left>102</left>
<top>78</top>
<right>177</right>
<bottom>98</bottom>
</rect>
<style>roundrect</style>
<showName> <true /> </showName>
<highlight> <false /> </highlight>
<autoHighlight> <false /> </autoHighlight>
<sharedHighlight> <true /> </sharedHighlight>
<family>0</family>
<titleWidth>0</titleWidth>
<icon>0</icon>
<textAlign>center</textAlign>
<font>Chicago</font>
<textSize>12</textSize>
<textStyle>plain</textStyle>
<name>See Script</name>
<script>on mouseUpedit script of button 1end mouseUp</script>
</part>
<part>
<id>3</id>
<type>button</type>
<visible> <true /> </visible>
<reserved5> 0 </reserved5>
<reserved4> 0 </reserved4>
<reserved3> 0 </reserved3>
<reserved2> 0 </reserved2>
<reserved1> 0 </reserved1>
<enabled> <true /> </enabled>
<rect>
<left>319</left>
<top>82</top>
<right>338</right>
<bottom>94</bottom>
</rect>
<style>transparent</style>
<showName> <false /> </showName>
<highlight> <false /> </highlight>
<autoHighlight> <false /> </autoHighlight>
<sharedHighlight> <true /> </sharedHighlight>
<family>0</family>
<titleWidth>0</titleWidth>
<icon>11893</icon>
<textAlign>center</textAlign>
<font>Chicago</font>
<textSize>12</textSize>
<textStyle>plain</textStyle>
<name></name>
<script>on mouseDownsend mouseDown to hittest(the mouseLoc, "btn")end mouseDown</script>
</part>
<part>
<id>5</id>
<type>button</type>
<visible> <true /> </visible>
<reserved5> 0 </reserved5>
<reserved4> 0 </reserved4>
<reserved3> 0 </reserved3>
<reserved2> 0 </reserved2>
<reserved1> 0 </reserved1>
<enabled> <true /> </enabled>
<rect>
<left>402</left>
<top>167</top>
<right>422</right>
<bottom>189</bottom>
</rect>
<style>transparent</style>
<showName> <false /> </showName>
<highlight> <false /> </highlight>
<autoHighlight> <false /> </autoHighlight>
<sharedHighlight> <true /> </sharedHighlight>
<family>0</family>
<titleWidth>0</titleWidth>
<icon>19678</icon>
<textAlign>center</textAlign>
<font>Chicago</font>
<textSize>12</textSize>
<textStyle>plain</textStyle>
<name></name>
<script>on mouseUplock screenshow cd fld "Menu Icon Details"unlock screen with wipe downend mouseUp</script>
</part>
<part>
<id>7</id>
<type>button</type>
<visible> <true /> </visible>
<reserved5> 0 </reserved5>
<reserved4> 0 </reserved4>
<reserved3> 0 </reserved3>
<reserved2> 0 </reserved2>
<reserved1> 0 </reserved1>
<enabled> <true /> </enabled>
<rect>
<left>372</left>
<top>233</top>
<right>392</right>
<bottom>255</bottom>
</rect>
<style>transparent</style>
<showName> <false /> </showName>
<highlight> <false /> </highlight>
<autoHighlight> <false /> </autoHighlight>
<sharedHighlight> <true /> </sharedHighlight>
<family>0</family>
<titleWidth>0</titleWidth>
<icon>19678</icon>
<textAlign>center</textAlign>
<font>Chicago</font>
<textSize>12</textSize>
<textStyle>plain</textStyle>
<name></name>
<script>on mouseUplock screenshow cd fld "Meta-Character Details"unlock screen with wipe downend mouseUp</script>
</part>
<part>
<id>6</id>
<type>field</type>
<visible> <false /> </visible>
<dontWrap> <false /> </dontWrap>
<dontSearch> <false /> </dontSearch>
<sharedText> <false /> </sharedText>
<fixedLineHeight> <false /> </fixedLineHeight>
<autoTab> <false /> </autoTab>
<lockText> <true /> </lockText>
<rect>
<left>44</left>
<top>106</top>
<right>468</right>
<bottom>342</bottom>
</rect>
<style>opaque</style>
<autoSelect> <false /> </autoSelect>
<showLines> <false /> </showLines>
<wideMargins> <false /> </wideMargins>
<multipleLines> <false /> </multipleLines>
<reservedFamily> 0 </reservedFamily>
<titleWidth>0</titleWidth>
<icon>0</icon>
<textAlign>left</textAlign>
<font>Geneva</font>
<textSize>10</textSize>
<textStyle>plain</textStyle>
<textHeight>13</textHeight>
<name>Meta-Character Details</name>
<script>on mouseUplock screenhide meunlock screen with wipe upend mouseUp</script>
</part>
<part>
<id>4</id>
<type>field</type>
<visible> <false /> </visible>
<dontWrap> <false /> </dontWrap>
<dontSearch> <false /> </dontSearch>
<sharedText> <false /> </sharedText>
<fixedLineHeight> <false /> </fixedLineHeight>
<autoTab> <false /> </autoTab>
<lockText> <true /> </lockText>
<rect>
<left>44</left>
<top>106</top>
<right>468</right>
<bottom>342</bottom>
</rect>
<style>opaque</style>
<autoSelect> <false /> </autoSelect>
<showLines> <false /> </showLines>
<wideMargins> <false /> </wideMargins>
<multipleLines> <false /> </multipleLines>
<reservedFamily> 0 </reservedFamily>
<titleWidth>0</titleWidth>
<icon>0</icon>
<textAlign>left</textAlign>
<font>Geneva</font>
<textSize>10</textSize>
<textStyle>plain</textStyle>
<textHeight>13</textHeight>
<name>Menu Icon Details</name>
<script>on mouseUplock screenhide meunlock screen with wipe upend mouseUp</script>
</part>
<content>
<layer>background</layer>
<id>3</id>
<text><span class="style5">mall and Color Icons!</span><span class="style1">Use ^ and a character for a cicn (color icon) or ICON (large icon) resource.Use ΓÇá (option-t) for a SICN (small icon) resource (use option on example).These character codes are explained by clicking on this balloon.There are a bunch of other meta-characters for menu styles, command keys and check marks. These meta-characters are restricted by this external so that you can use them in menu items too. An explanation of these restrictions is available by clicking on this balloon.SICNs will not appear on menu items which have submenus. This is because the menu manager uses the same field for the SICN and hierarchical menu ID. It's one or the other. I chose to give the menu precedence.Everything here except for the SICNs is free from the menu manager.</span></text>
</content>
<content>
<layer>card</layer>
<id>4</id>
<text><span class="style1">CONs, cicns, and SICNs use a character code to indicate the icon number. These codes start with the character 1 for ICON or SICN number 257. There are a limited number of characters above 1 which means that all ICON and SICN resources you want to use in a menu must be numbered 257 through 334 inclusive so that you can specify a character for the code.Note that these characters grow through the ASCII chart, not numerically. (e.g. 2=258, 9=265, :=266, ;=267, <=268, ==269, >=270, ?=271, @=272, A=273, Z=298, [=299, \=300, ]=301, ^=302, _=303, `=304, a=305, z=330, {=331, |=332, }=333, ~=334)Use the expression </span><span class="style4">NumToChar(iconNum-208)</span><span class="style1"> to get the proper character given the number iconNum in the range 257 through 334.You cannot use an icon or SICN of ID 267 because it would be a ; character which would mess up the menu parsing. This is my fault but it would be painful to fix.</span><span class="style3"> Click on this field to hide it.</span></text>
</content>
<content>
<layer>card</layer>
<id>6</id>
<text><span class="style1">enu meta-characters work, with some restrictions that I created so that you can include them in the menu item text when these conditions aren't met. This makes these meta-characters a lot easier to use, in my humble opinion, but I should lay down the ground rules. Here's what this external expects to see for meta-characters.ICON or cicn = ^ followed by a character between '1' and '~' anywhere in the menu.SICN = ΓÇá followed by a character between '1' and '~' anywhere in the menu text. These cannot appear on menus with hierarchical menus or command keys.check mark = !, optionally followed by the character to use as check mark. Only available as first character or last character. If using hierarchical menu or command key, it </span><span class="style7">must </span><span class="style1"> be the first character.styled text = < followed by B, I, S or O (capitals only) anywhere in the text. B is bold, I is italic, S is shadow and O is outline.disabled menus = ( as the first character of the text.command keys = / followed by a character makes that character the command key. This only works as the last characters of the menu. Items which have hierarchical menus off them cannot have command keys.</span><span class="style3"> Click on this field to hide it.</span></text>
</content>
<name></name>
<script>on closeCardif visible of cd fld 1 thenclick at loc of cd fld 1end ifif visible of cd fld 2 thenclick at loc of cd fld 2end ifpass closeCardend closeCard</script>
</card>
card_5287.xml
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE card PUBLIC "-//Apple, Inc.//DTD card V 2.0//EN" "" >
<script>on mouseDownset hilite of me to true-- Note that menu meta-characters work-- ^ for icon-- † for small icon-- ! for check mark-- < for style-- ( for disabled items-- / for command keys-- See IM I-346 to 349 for more detailsglobal savedItemif savedItem is empty then put 2 into savedItem-- the extra commas are for adding the diamonds to the threes-- null items don't appear in the popup menuglobal hasColorQDif xor(the optionKey is down, hasColorQD) thenput "Item1,1,2,3," & return & "Item2,;Item3^2,One,Two,Three,;" & ¬"Item4^" & NumToChar(270-208) & ",Isn’t,This,Fun?" & return & ¬"Cool Stuff,slashes /,dashes -,carets ^,exclamations !,angle brackets <>,parentheses ();(-;" & ¬"Go to,Next Card<I/3,Last Card/4,Help/?,Home^1/H,(-,Heaven/Hell<B<O,Jail;" into stuffelseput "Item1,1,2,3," & return & "Item2,;Item3,One,Two,Three,;" & ¬"Item4^" & NumToChar(270-208) & ",Isn’t,This,Fun?" & return & ¬"Cool Stuff,slashes /,dashes -,carets ^,exclamations !,angle brackets <>,parentheses ();(-;" & ¬"Go to,Next Card<I/3,Last Card/4,Help/?,Home†6,(-,Heaven/Hell<B<O,Jail;" into stuffend if-- the count of items to mark the ones we wantput "!" after item savedItem+1 of stuffput "!" after item savedItem+6 of stuffput HPopUpMenu(stuff, 0, bottom of me, left of me) into junkset hilite of me to falseif item 1 of junk is not empty thenif item 1 of junk is "Go to" and item 2 of junk is not empty thenvisual scroll up to blackvisual scroll upgo to item 2 of junkelseput junkif item 3 of junk is in "13" and item 4 of junk is in "123"then put item 4 of junk into savedItemrepeat for 3000if the mouse is down then if the mouse is up then exit repeatend repeathide msgend ifend ifend mouseDown</script>
</part>
<part>
<id>12</id>
<type>button</type>
<visible> <true /> </visible>
<reserved5> 0 </reserved5>
<reserved4> 0 </reserved4>
<reserved3> 0 </reserved3>
<reserved2> 0 </reserved2>
<reserved1> 0 </reserved1>
<enabled> <true /> </enabled>
<rect>
<left>102</left>
<top>78</top>
<right>177</right>
<bottom>98</bottom>
</rect>
<style>roundrect</style>
<showName> <true /> </showName>
<highlight> <false /> </highlight>
<autoHighlight> <false /> </autoHighlight>
<sharedHighlight> <true /> </sharedHighlight>
<family>0</family>
<titleWidth>0</titleWidth>
<icon>0</icon>
<textAlign>center</textAlign>
<font>Chicago</font>
<textSize>12</textSize>
<textStyle>plain</textStyle>
<name>See Script</name>
<script>on mouseUpedit script of button 1end mouseUp</script>
</part>
<part>
<id>14</id>
<type>button</type>
<visible> <true /> </visible>
<reserved5> 0 </reserved5>
<reserved4> 0 </reserved4>
<reserved3> 0 </reserved3>
<reserved2> 0 </reserved2>
<reserved1> 0 </reserved1>
<enabled> <true /> </enabled>
<rect>
<left>311</left>
<top>82</top>
<right>330</right>
<bottom>94</bottom>
</rect>
<style>transparent</style>
<showName> <false /> </showName>
<highlight> <false /> </highlight>
<autoHighlight> <false /> </autoHighlight>
<sharedHighlight> <true /> </sharedHighlight>
<family>0</family>
<titleWidth>0</titleWidth>
<icon>11893</icon>
<textAlign>center</textAlign>
<font>Chicago</font>
<textSize>12</textSize>
<textStyle>plain</textStyle>
<name></name>
<script>on mouseDownsend mouseDown to hittest(the mouseLoc, "btn")end mouseDown</script>
</part>
<content>
<layer>background</layer>
<id>3</id>
<text><span class="style5">ierarchical Popup Menus!</span><span class="style1">This example demonstrates how to create a drop down menu with submenus. This XFCN is limited to one level of submenus which should be enough for most purposes.The important thing to see is the format of the menuitem string.Main1,Sub1,Sub2,Sub3;Main2,Sub1,Sub2,Sub3;Main3;Main4,Sub1,Sub2Please note that the returned values include both menu items chosen and their numbers. You can use the numbers to index into other arrays or just use the returned values.I use the returned numbers to handle the diamond mark. See how it remembers what you have chosen. I tied both menus to the same variable which is probably not how it would be done in real life.Once again, the commas can be anything but must match the itemDelimiter property.</span></text>
</content>
<name></name>
<script></script>
</card>
card_8262.xml
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE card PUBLIC "-//Apple, Inc.//DTD card V 2.0//EN" "" >
<script>on mouseDownset hilite of me to trueput "A.Abel, Jon.Ackface, Nermal;B.Bonzo, Ron.Barty, Billy;C.Clown, Krusty.Card, Orson" into stuffset itemDelimiter to "."put HPopUpMenu(stuff, 0, bottom of me, left of me) into junkset hilite of me to falseif item 1 of junk is not empty thenput junkrepeat for 3000if the mouse is down then if the mouse is up then exit repeatend repeathide msgend ifset itemDelimiter to commaend mouseDown</script>
</part>
<part>
<id>12</id>
<type>button</type>
<visible> <true /> </visible>
<reserved5> 0 </reserved5>
<reserved4> 0 </reserved4>
<reserved3> 0 </reserved3>
<reserved2> 0 </reserved2>
<reserved1> 0 </reserved1>
<enabled> <true /> </enabled>
<rect>
<left>102</left>
<top>78</top>
<right>177</right>
<bottom>98</bottom>
</rect>
<style>roundrect</style>
<showName> <true /> </showName>
<highlight> <false /> </highlight>
<autoHighlight> <false /> </autoHighlight>
<sharedHighlight> <true /> </sharedHighlight>
<family>0</family>
<titleWidth>0</titleWidth>
<icon>0</icon>
<textAlign>center</textAlign>
<font>Chicago</font>
<textSize>12</textSize>
<textStyle>plain</textStyle>
<name>See Script</name>
<script>on mouseUpedit script of button 1end mouseUp</script>
</part>
<part>
<id>14</id>
<type>button</type>
<visible> <true /> </visible>
<reserved5> 0 </reserved5>
<reserved4> 0 </reserved4>
<reserved3> 0 </reserved3>
<reserved2> 0 </reserved2>
<reserved1> 0 </reserved1>
<enabled> <true /> </enabled>
<rect>
<left>311</left>
<top>82</top>
<right>330</right>
<bottom>94</bottom>
</rect>
<style>transparent</style>
<showName> <false /> </showName>
<highlight> <false /> </highlight>
<autoHighlight> <false /> </autoHighlight>
<sharedHighlight> <true /> </sharedHighlight>
<family>0</family>
<titleWidth>0</titleWidth>
<icon>11893</icon>
<textAlign>center</textAlign>
<font>Chicago</font>
<textSize>12</textSize>
<textStyle>plain</textStyle>
<name></name>
<script>on mouseDownsend mouseDown to hittest(the mouseLoc, "btn")end mouseDown</script>
</part>
<part>
<id>15</id>
<type>button</type>
<visible> <false /> </visible>
<reserved5> 0 </reserved5>
<reserved4> 0 </reserved4>
<reserved3> 0 </reserved3>
<reserved2> 0 </reserved2>
<reserved1> 0 </reserved1>
<enabled> <true /> </enabled>
<rect>
<left>236</left>
<top>74</top>
<right>336</right>
<bottom>101</bottom>
</rect>
<style>transparent</style>
<showName> <false /> </showName>
<highlight> <false /> </highlight>
<autoHighlight> <false /> </autoHighlight>
<sharedHighlight> <true /> </sharedHighlight>
<family>0</family>
<titleWidth>0</titleWidth>
<icon>0</icon>
<textAlign>center</textAlign>
<font>Chicago</font>
<textSize>12</textSize>
<textStyle>plain</textStyle>
<name>Warning</name>
<script>on mouseDownanswer "This example uses the itemDelimiter property which is not available in version" && ¬the version && "of Hypercard."end mouseDown</script>
</part>
<content>
<layer>background</layer>
<id>3</id>
<text><span class="style5">lternate ItemDelimiters!</span><span class="style1">This example demonstrates how to use an alternate itemDelimiter so that you can get commas in the menu items. This only works with version 2.1 or greater of Hypercard.You can change the itemDelimiter property with the command: set itemDelimiter to "."You should reset the property as soon as possible with the command: set itemDelimiter to commaYou can set the itemDelimiter to anything you like and use that as either your delimiter for regular popups or as the seperator for hierarchical items.</span></text>
</content>
<name></name>
<script>on openCardglobal seenWarningif the version < 2.1 thenif seenWarning = ""then answer "IΓÇÖm sorry, but version 2.1 is required for this example."put "seen it" into seenWarningshow button "Warning"end ifpass openCardend openCardon closeCardhide button "Warning"pass closeCardend closeCard</script>
</card>
card_6769.xml
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE card PUBLIC "-//Apple, Inc.//DTD card V 2.0//EN" "" >
<script>on mouseDown-- use MENU resource ID instead of stringset hilite of me to trueput HPopUpMenu(257, 0, bottom of me, left of me) into junkset hilite of me to falseif item 1 of junk is not empty thenif the number of items of junk > 4 thenanswer junkelseput junkrepeat for 3000if the mouse is down then if the mouse is up then exit repeatend repeathide msgend ifend ifend mouseDown</script>
</part>
<part>
<id>12</id>
<type>button</type>
<visible> <true /> </visible>
<reserved5> 0 </reserved5>
<reserved4> 0 </reserved4>
<reserved3> 0 </reserved3>
<reserved2> 0 </reserved2>
<reserved1> 0 </reserved1>
<enabled> <true /> </enabled>
<rect>
<left>102</left>
<top>78</top>
<right>177</right>
<bottom>98</bottom>
</rect>
<style>roundrect</style>
<showName> <true /> </showName>
<highlight> <false /> </highlight>
<autoHighlight> <false /> </autoHighlight>
<sharedHighlight> <true /> </sharedHighlight>
<family>0</family>
<titleWidth>0</titleWidth>
<icon>0</icon>
<textAlign>center</textAlign>
<font>Chicago</font>
<textSize>12</textSize>
<textStyle>plain</textStyle>
<name>See Script</name>
<script>on mouseUpedit script of button 1end mouseUp</script>
</part>
<part>
<id>14</id>
<type>button</type>
<visible> <true /> </visible>
<reserved5> 0 </reserved5>
<reserved4> 0 </reserved4>
<reserved3> 0 </reserved3>
<reserved2> 0 </reserved2>
<reserved1> 0 </reserved1>
<enabled> <true /> </enabled>
<rect>
<left>311</left>
<top>82</top>
<right>330</right>
<bottom>94</bottom>
</rect>
<style>transparent</style>
<showName> <false /> </showName>
<highlight> <false /> </highlight>
<autoHighlight> <false /> </autoHighlight>
<sharedHighlight> <true /> </sharedHighlight>
<family>0</family>
<titleWidth>0</titleWidth>
<icon>11893</icon>
<textAlign>center</textAlign>
<font>Chicago</font>
<textSize>12</textSize>
<textStyle>plain</textStyle>
<name></name>
<script>on mouseDownsend mouseDown to hittest(the mouseLoc, "btn")end mouseDown</script>
</part>
<content>
<layer>background</layer>
<id>3</id>
<text><span class="style5">rbitrarily Deep Resource Menus!</span><span class="style1">This example demonstrates how to create a drop down menu with several levels of submenus from a MENU resource.You specify a menu resource simply by replacing the menu string parameter with the number of the MENU resource and creating the MENU resource with ResEdit or Resourcerer.Menu resources are the only way to get this XFCN to show menus deeper than one sublevel. The only limit to menu depth is the number of characters returned. If the text of all the menu items exceeds 255 characters then only the menu numbers will be returned, otherwise the text of all the menu items will be returned, followed by the numbers.The advantage of using MENU resources is that they are faster on slow machines since the XFCN doesnΓÇÖt have to parse the input string.</span></text>
</content>
<name></name>
<script></script>
</card>
card_2792.xml
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE card PUBLIC "-//Apple, Inc.//DTD card V 2.0//EN" "" >
<script>on mouseDownglobal menuStuff, lastMenuChoice-- menuStuff is initialized in the card's openCard handler which-- calls the initMenu handler below in this buttonset hilite of me to trueif the optionKey is down then initMenuif lastMenuChoice = "" thenget bottom of me + 1else get top of meput menuStuff into tempMenusif lastMenuChoice Γëá "" then put "!ΓÇó" after line lastMenuChoice of tempMenusput HPopUpMenu(tempMenus, -lastMenuChoice, it, left of me, Geneva, 9) into junkset hilite of me to falseif junk Γëá "" thenif junk contains "Error:" then answer junk with "Whoops"else put word 3 of item 1 of junk into lastMenuChoiceend ifend mouseDownon initMenuglobal menuStuffput "" into menuStuffget 100repeat with i = 1 to itput "Menu Item" && i && "/" && it into line i of menuStuffend repeatend initMenu</script>
</part>
<part>
<id>3</id>
<type>button</type>
<visible> <true /> </visible>
<reserved5> 0 </reserved5>
<reserved4> 0 </reserved4>
<reserved3> 0 </reserved3>
<reserved2> 0 </reserved2>
<reserved1> 0 </reserved1>
<enabled> <true /> </enabled>
<rect>
<left>102</left>
<top>78</top>
<right>177</right>
<bottom>98</bottom>
</rect>
<style>roundrect</style>
<showName> <true /> </showName>
<highlight> <false /> </highlight>
<autoHighlight> <false /> </autoHighlight>
<sharedHighlight> <true /> </sharedHighlight>
<family>0</family>
<titleWidth>0</titleWidth>
<icon>0</icon>
<textAlign>center</textAlign>
<font>Chicago</font>
<textSize>12</textSize>
<textStyle>plain</textStyle>
<name>See Script</name>
<script>on mouseUpedit script of button 1end mouseUp</script>
</part>
<part>
<id>4</id>
<type>button</type>
<visible> <true /> </visible>
<reserved5> 0 </reserved5>
<reserved4> 0 </reserved4>
<reserved3> 0 </reserved3>
<reserved2> 0 </reserved2>
<reserved1> 0 </reserved1>
<enabled> <true /> </enabled>
<rect>
<left>313</left>
<top>85</top>
<right>332</right>
<bottom>97</bottom>
</rect>
<style>transparent</style>
<showName> <false /> </showName>
<highlight> <false /> </highlight>
<autoHighlight> <false /> </autoHighlight>
<sharedHighlight> <true /> </sharedHighlight>
<family>0</family>
<titleWidth>0</titleWidth>
<icon>9940</icon>
<textAlign>center</textAlign>
<font>Chicago</font>
<textSize>12</textSize>
<textStyle>plain</textStyle>
<name></name>
<script>on mouseDownsend mouseDown to hittest(the mouseLoc, "btn")end mouseDown</script>
</part>
<content>
<layer>background</layer>
<id>3</id>
<text><span class="style5">ifferent Fonts and Sizes!</span><span class="style1">The above example shows how Geneva 9 looks in a hierarchical popup menu. You can use any font in place of Chicago 12, which is the standard System font.Smaller font sizes don't look as good in hierarchical menus since the diamonds get shrunk down kind of ugly. I would recommend avoiding hierarchical menus with small font sizes. Regular popups look fine in small sizes.If you specify a font name that doesn't exist then the font and size are ignored and the system font is used instead. For this reason you should avoid non-standard fonts in stacks that you distribute.Note the use of slashes in the menu items. Cool huh?</span></text>
</content>
<name>Home</name>
<script>on openCardsend initMenu to btn "Example"pass openCardend openCard</script>
</card>
card_8736.xml
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE card PUBLIC "-//Apple, Inc.//DTD card V 2.0//EN" "" >
<script>on mouseDownget "Fonts,®FONT;Sounds,®snd ;Externals,XFCNs<I,(-,®XFCN,(-,XCMDs<I,(-,®XCMD"set hilite of me to trueput HPopUpMenu(it, 0, bottom of me, left of me) into junkset hilite of me to falseif junk ≠ "" thenif junk contains "Error:" then answer junk with "Whoops"if item 1 of junk = "Sounds" then play item 2 of junkput junkrepeat for 3000if the mouse is down then if the mouse is up then exit repeatend repeathide msgend ifend mouseDown</script>
</part>
<part>
<id>3</id>
<type>button</type>
<visible> <true /> </visible>
<reserved5> 0 </reserved5>
<reserved4> 0 </reserved4>
<reserved3> 0 </reserved3>
<reserved2> 0 </reserved2>
<reserved1> 0 </reserved1>
<enabled> <true /> </enabled>
<rect>
<left>102</left>
<top>78</top>
<right>177</right>
<bottom>98</bottom>
</rect>
<style>roundrect</style>
<showName> <true /> </showName>
<highlight> <false /> </highlight>
<autoHighlight> <false /> </autoHighlight>
<sharedHighlight> <true /> </sharedHighlight>
<family>0</family>
<titleWidth>0</titleWidth>
<icon>0</icon>
<textAlign>center</textAlign>
<font>Chicago</font>
<textSize>12</textSize>
<textStyle>plain</textStyle>
<name>See Script</name>
<script>on mouseUpedit script of button 1end mouseUp</script>
</part>
<part>
<id>4</id>
<type>button</type>
<visible> <true /> </visible>
<reserved5> 0 </reserved5>
<reserved4> 0 </reserved4>
<reserved3> 0 </reserved3>
<reserved2> 0 </reserved2>
<reserved1> 0 </reserved1>
<enabled> <true /> </enabled>
<rect>
<left>317</left>
<top>82</top>
<right>336</right>
<bottom>94</bottom>
</rect>
<style>transparent</style>
<showName> <false /> </showName>
<highlight> <false /> </highlight>
<autoHighlight> <false /> </autoHighlight>
<sharedHighlight> <true /> </sharedHighlight>
<family>0</family>
<titleWidth>0</titleWidth>
<icon>11893</icon>
<textAlign>center</textAlign>
<font>Chicago</font>
<textSize>12</textSize>
<textStyle>plain</textStyle>
<name></name>
<script>on mouseDownsend mouseDown to hittest(the mouseLoc, "btn")end mouseDown</script>
</part>
<part>
<id>7</id>
<type>button</type>
<visible> <true /> </visible>
<reserved5> 0 </reserved5>
<reserved4> 0 </reserved4>
<reserved3> 0 </reserved3>
<reserved2> 0 </reserved2>
<reserved1> 0 </reserved1>
<enabled> <true /> </enabled>
<rect>
<left>267</left>
<top>107</top>
<right>313</right>
<bottom>127</bottom>
</rect>
<style>shadow</style>
<showName> <true /> </showName>
<highlight> <false /> </highlight>
<autoHighlight> <false /> </autoHighlight>
<sharedHighlight> <true /> </sharedHighlight>
<family>0</family>
<titleWidth>0</titleWidth>
<icon>0</icon>
<textAlign>left</textAlign>
<font>Chicago</font>
<textSize>12</textSize>
<textStyle>plain</textStyle>
<name>∩ú┐</name>
<script>on mouseDownset hilite of me to trueput HPopUpMenu("®DRVR", 0, bottom of me, left of me) into junkset hilite of me to falseif junk ≠ "" thenif junk contains "Error:" then answer junk with "Whoops"put junkdoMenu item 1 of junkend ifend mouseDown</script>
</part>
<part>
<id>11</id>
<type>button</type>
<visible> <true /> </visible>
<reserved5> 0 </reserved5>
<reserved4> 0 </reserved4>
<reserved3> 0 </reserved3>
<reserved2> 0 </reserved2>
<reserved1> 0 </reserved1>
<enabled> <true /> </enabled>
<rect>
<left>288</left>
<top>111</top>
<right>307</right>
<bottom>123</bottom>
</rect>
<style>transparent</style>
<showName> <false /> </showName>
<highlight> <false /> </highlight>
<autoHighlight> <false /> </autoHighlight>
<sharedHighlight> <true /> </sharedHighlight>
<family>0</family>
<titleWidth>0</titleWidth>
<icon>11893</icon>
<textAlign>center</textAlign>
<font>Chicago</font>
<textSize>12</textSize>
<textStyle>plain</textStyle>
<name></name>
<script>on mouseDownsend mouseDown to hittest(the mouseLoc, "btn")end mouseDown</script>
</part>
<part>
<id>12</id>
<type>button</type>
<visible> <true /> </visible>
<reserved5> 0 </reserved5>
<reserved4> 0 </reserved4>
<reserved3> 0 </reserved3>
<reserved2> 0 </reserved2>
<reserved1> 0 </reserved1>
<enabled> <true /> </enabled>
<rect>
<left>383</left>
<top>108</top>
<right>458</right>
<bottom>128</bottom>
</rect>
<style>roundrect</style>
<showName> <true /> </showName>
<highlight> <false /> </highlight>
<autoHighlight> <false /> </autoHighlight>
<sharedHighlight> <true /> </sharedHighlight>
<family>0</family>
<titleWidth>0</titleWidth>
<icon>0</icon>
<textAlign>center</textAlign>
<font>Chicago</font>
<textSize>12</textSize>
<textStyle>plain</textStyle>
<name>See Script</name>
<script>on mouseUpedit script of button 4end mouseUp</script>
</part>
<content>
<layer>background</layer>
<id>3</id>
<text><span class="style5">esource List Menus!</span><span class="style1">There is a special form of menu item text that allows you to get a list of resources into a menu without any additional effort. You simply specify the resource type (a four character code) preceeded by the character ® (option-r).In the example above the font menu is "®FONT" while the sound menu is "®snd " and the external menu is both "®XFCN" and "®XCMD". The other example uses "®DRVR".You can use these special menu items in MENU resources too.If you are concerned about the use of FONTs with regards to FONDs, NFNTs and sfnts, don’t. The routine we call deals with FONTs specifically and provides a list of all installed FONTs, regardless of their forms.The toolbox also automatically sorts this list for us. Thanks.</span></text>
</content>
<name>Home</name>
<script></script>
</card>
card_3475.xml
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE card PUBLIC "-//Apple, Inc.//DTD card V 2.0//EN" "" >
<script>on mouseUpif the optionKey is up thenask file "Save as…" with "HPopup.p"if it is empty then exit mouseUpput it into lastFileNameopen file lastFileNamewrite card field "Code" to file lastFileNameclose file lastFileNameelseanswer file "Where is the source?" of type "TEXT"if it is empty then exit mouseUpwriteProtect falseput it into fileNameopen file fileNameread from file fileName until eofput it into cd fld "Code"close file fileNameend ifend mouseUp</script>
</part>
<part>
<id>4</id>
<type>button</type>
<visible> <true /> </visible>
<reserved5> 0 </reserved5>
<reserved4> 0 </reserved4>
<reserved3> 0 </reserved3>
<reserved2> 0 </reserved2>
<reserved1> 0 </reserved1>
<enabled> <true /> </enabled>
<rect>
<left>466</left>
<top>264</top>
<right>512</right>
<bottom>342</bottom>
</rect>
<style>transparent</style>
<showName> <false /> </showName>
<highlight> <true /> </highlight>
<autoHighlight> <false /> </autoHighlight>
<sharedHighlight> <true /> </sharedHighlight>
<family>0</family>
<titleWidth>0</titleWidth>
<icon>11045</icon>
<textAlign>center</textAlign>
<font>Chicago</font>
<textSize>12</textSize>
<textStyle>plain</textStyle>
<name>Home</name>
<script>on mouseUpif the stacks contains "Home"and number of lines of the stacks > 1 thendoMenu "Close Stack"end ifvisual scroll upgo homeend mouseUp</script>
</part>
<part>
<id>5</id>
<type>button</type>
<visible> <true /> </visible>
<reserved5> 0 </reserved5>
<reserved4> 0 </reserved4>
<reserved3> 0 </reserved3>
<reserved2> 0 </reserved2>
<reserved1> 0 </reserved1>
<enabled> <true /> </enabled>
<rect>
<left>294</left>
<top>242</top>
<right>376</right>
<bottom>264</bottom>
</rect>
<style>roundrect</style>
<showName> <true /> </showName>
<highlight> <false /> </highlight>
<autoHighlight> <false /> </autoHighlight>
<sharedHighlight> <true /> </sharedHighlight>
<family>0</family>
<titleWidth>0</titleWidth>
<icon>0</icon>
<textAlign>center</textAlign>
<font>Chicago</font>
<textSize>12</textSize>
<textStyle>plain</textStyle>
<name>Show Code</name>
<script>on mouseUplock screenif visible of card field "Code" then hide card field "Code"else show card field "Code"unlock screen with dissolveend mouseUp</script>
</part>
<part>
<id>6</id>
<type>button</type>
<visible> <true /> </visible>
<reserved5> 0 </reserved5>
<reserved4> 0 </reserved4>
<reserved3> 0 </reserved3>
<reserved2> 0 </reserved2>
<reserved1> 0 </reserved1>
<enabled> <true /> </enabled>
<rect>
<left>197</left>
<top>285</top>
<right>384</right>
<bottom>307</bottom>
</rect>
<style>roundrect</style>
<showName> <true /> </showName>
<highlight> <false /> </highlight>
<autoHighlight> <true /> </autoHighlight>
<sharedHighlight> <true /> </sharedHighlight>
<family>0</family>
<titleWidth>0</titleWidth>
<icon>0</icon>
<textAlign>center</textAlign>
<font>Chicago</font>
<textSize>12</textSize>
<textStyle>plain</textStyle>
<name>Install HPopUpMenu</name>
<script>on mouseUpanswer file "Install HPopUpMenu into…" of type stackif it ≠ "" thenset cursor to watchput it into theTargetget second word of the long name of stackput it into theSourceResCopy value of theSource, theTarget, "XFCN", "HPopUpMenu"if the result = "" then answer "Installation complete."else answer the resultend ifend mouseUp</script>
</part>
<part>
<id>2</id>
<type>field</type>
<visible> <false /> </visible>
<dontWrap> <false /> </dontWrap>
<dontSearch> <false /> </dontSearch>
<sharedText> <false /> </sharedText>
<fixedLineHeight> <true /> </fixedLineHeight>
<autoTab> <false /> </autoTab>
<lockText> <true /> </lockText>
<rect>
<left>0</left>
<top>0</top>
<right>512</right>
<bottom>342</bottom>
</rect>
<style>scrolling</style>
<autoSelect> <false /> </autoSelect>
<showLines> <false /> </showLines>
<wideMargins> <false /> </wideMargins>
<multipleLines> <false /> </multipleLines>
<reservedFamily> 0 </reservedFamily>
<titleWidth>0</titleWidth>
<icon>0</icon>
<textAlign>left</textAlign>
<font>Monaco</font>
<textSize>9</textSize>
<textStyle>plain</textStyle>
<textHeight>12</textHeight>
<name>Code</name>
<script>on mouseUplock screenhide card field "Code"set scroll of target to 0unlock screen with dissolveend mouseUp</script>
</part>
<content>
<layer>background</layer>
<id>3</id>
<text>Some of the features I worked hard to include are the ability to select the items on the main menu and to correspondingly not select disabled items.I also went to some trouble to allow long strings so that you can have large menus. I also added the ability to use small icons, have menu style metacharacters in menu items, menu resources and resource menus. Please let me know if you find anything that doesn't work as it should.In the spirit of cooperation and the spread of knowledge, I have included the source code to this XFCN. Simply press the magic button to get the file written to disk.</text>
</content>
<content>
<layer>card</layer>
<id>2</id>
<text>{$R-}{$S HPopUpMenu }(*This source code © 1989, 1990, 1991, 1992, 1993 by Jon Pugh(408) 862-7094jpugh@apple.comApplelink: JONPUGHHPopUpMenu({ MenuItems | MENU resource id }, CheckedItem, Top, Left [, Font, Size]);This HyperCard external function returns the selection from a HierarchicalPopUp menu created from a hypercard item list (the first parameter). Thesecond parameter is the item to be checked. Pass a negative number to avoidchecking anything and still place that item as the default.The menu is placed on the screen so that the checked item is at the position top,left. The menu syntax is that the itemDelimiter seperates hierarchicalitems and semicolon or return seperates regular menu items except when there are nohierarchical menus you may use all itermDelimiters, semicolons, or returns.The normal itemDelimiter is a comma.i.e.item1,1,2,3;item2;item3,4,5,6is a menu where the format is:item1 1 2 3item2item3 4 5 6All the standard menu metacharacters work, in addition to my new † metacharacterwhich is option-t. This works just like the icon metacharacter ^ except that instead of using an ICON resource, it uses an SICN resource.I have also added a new metacharacter, ® which allows you to specify a resourcetype for a menu of resources. You may place this meta-menu item in anyposition and it will expand into a list of resources. For example, "®FONT" willbecome a list of FONTs while "®snd " becomes a list of sounds. You can also use"®DRVR" to get the Apple Menu as a popup. I had to strip the nulls from thenames returned here to get these out of Hypercard.To compile and link using MPW executethe following:save -apascal HPopUp.plink -o HierPopUp -rt XFCN=3498 ∂ -m ENTRYPOINT -sg HPopUpMenu HPopUp.p.o ∂ "{PLibraries}"Paslib.o ∂ "{Libraries}"Interface.o ∂ "{Libraries}"HyperXLib.oI must thank Andrew Gilmartin for his initial example although I havecompletely rewritten anything that might have been from him originally.*)UNIT HPopUpUnit;INTERFACEUSES SysEqu, MemTypes, QuickDraw, OSIntf, ToolIntf, PackIntf, HyperXCmd;PROCEDURE EntryPoint(paramPtr: XCmdPtr);IMPLEMENTATIONCONST MenuDisableAddr = $B54; kSmallIconCmd = $1E; SysFontFamAddr = $0BA6; SysFontSizeAddr = $0BA8; LastSpExtraAddr = $0B4C; styleMetaChars = ['B','O','I','S','U'];TYPE bigStringHandle = ^bigStringPtr; bigStringPtr = ^bigString; bigString = packed array [1..maxInt] OF char;PROCEDURE HPopUpMenu(paramPtr: XCmdPtr); FORWARD;PROCEDURE EntryPoint(paramPtr: XCmdPtr);BEGINHPopUpMenu(paramPtr)END; { entrypoint }PROCEDURE HPopUpMenu(paramPtr: XCmdPtr);CONST MaxMenus = 300; MenuID = 128;VAR pt : Point; p : bigStringHandle; pp : bigStringPtr; junk : Ptr; aWord : ^Integer; Menu : Array [0..MaxMenus] OF MenuHandle; aLongInt : ^LongInt; WinMgr : ^GrafPtr; CWinMgr : ^CGrafPtr; scanning, enabled, hasSubMenus : Boolean; CheckedItem, SelectedItem : LongInt; MaxMenu, h, i, j, l, ItemCount, menuCount, Len, Start, theIcon : Integer; theSize, oldSize, theFont, oldFont, oldSysSize, oldSysFont, oldSysCSize, oldSysCFont : Integer; c, delim : Char; MenuItems, AllItems, theFontName : Str255; FUNCTION myNumToStr (num : LongInt) : Str255; VAR t : Str255; BEGIN NumToStr(ParamPtr, num, t); myNumToStr := t; END; { myNumToStr } FUNCTION ParamToNum(Param: Handle): LongInt; VAR Str: Str255; BEGIN ZeroToPas(ParamPtr, Param^, Str); ParamToNum := StrToNum(ParamPtr, Str); END; { ParamToNum } FUNCTION NumToParam(Num: LongInt): Handle; VAR Str: Str31; BEGIN Str := myNumToStr(Num); NumToParam := PasToZero(ParamPtr, Str) END; { NumToParam } FUNCTION myCopy (p : bigStringHandle; f, l : Integer) : Str255; VAR t : Str255; i : Integer; BEGIN t := ''; FOR i := 1 TO l DO BEGIN t := Concat(t,' '); t[i] := p^^[f+i-1]; END; myCopy := t; END; { myCopy } PROCEDURE Bomb (err : Integer); VAR t : Str255; BEGIN IF err <> noErr THEN BEGIN NumToString(err, t); SendCardMessage(ParamPtr, Concat('Put "Error : ', t, '"')); END; END; { Bomb } PROCEDURE TidyUp; VAR j : Integer; BEGIN FOR j := 0 TO menuCount DO IF Menu[j] <> NIL THEN BEGIN DeleteMenu(Menu[j]^^.menuID); DisposeMenu(Menu[j]); END; END; { Tidy Up } FUNCTION SmallIcon(VAR menuText : Str255; VAR theIcon : Integer) : Boolean; VAR l : LongInt; i : Integer; t : Str255; BEGIN { Check if the † metacharacter is present } { Remove it and everything after it } { Return true only if this item doesn't already have a submenu } i := Pos('†', menuText); IF i = 0 THEN SmallIcon := False ELSE BEGIN t := Copy(menuText, i+1, length(menuText) - i); Delete(menuText, i, 255); l := 0; StringToNum(t, l); theIcon := LoWord(l); SmallIcon := theIcon > 0; IF t[length(t)-1] = '/' THEN BEGIN menuText := Concat(menuText, Copy(t, length(t)-1, 2)); SmallIcon := False; END; END; END; { SmallIcon } PROCEDURE DependMenu (theMenu : MenuHandle; item : Str255); VAR i, j : Integer; t : Str255; BEGIN t := item; FOR i := 1 TO length(t) DO IF (t[i] = '/') & (i <> length(t)-1) THEN t[i] := '\' ELSE IF ((t[i] = '^') | (t[i] = '†')) THEN BEGIN IF (i = length(t)) | NOT ((t[i+1] >= '1') & (t[i+1] <= '~')) THEN t[i] := 'v' END ELSE IF (t[i] = '<') & NOT ((i <> length(t)) & (t[i+1] IN styleMetaChars)) THEN t[i] := '>' ELSE IF (t[i] = '!') & (i <> length(t)-1) THEN t[i] := '1' ELSE IF (t[i] = '(') & (i <> 1) THEN t[i] := ')'; AppendMenu(theMenu, t); t := ''; i := 1; j := 1; WHILE i <= length(item) DO BEGIN IF (item[i] = '/') & (i = length(item)-1) THEN i := i + 2 ELSE IF ((item[i] = '^') | (item[i] = '†')) & (i <> length(item)) & (item[i+1] >= '1') & (item[i+1] <= '~') THEN i := i + 2 ELSE IF (i = 1) & (item[i] = '(') THEN i := 2 ELSE IF (item[i] = '<') & (i <> length(item)) & (item[i+1] IN styleMetaChars) THEN i := i + 2 ELSE IF (item[i] = '!') & ((i = length(item)-1) | (i = 1)) THEN i := i + 2 ELSE BEGIN t[j] := item[i]; t[0] := char(j); j := j + 1; i := i + 1; END; END; i := CountMItems(theMenu); SetItem(theMenu, i, t); END; { DependMenu } FUNCTION ResourceType (t : Str255) : ResType; VAR theType : ResType; BEGIN BlockMove(@t[2], @thetype, 4); ResourceType := theType; END; { ResourceType } PROCEDURE StringMenu; VAR i : Integer; BEGIN { Make a copy of the input string that we can mess with } p := bigStringHandle(paramPtr^.Params[1]); Bomb(HandToHand(Handle(p))); len := StringLength(ParamPtr, paramPtr^.Params[1]^); { Check for all commas and convert them to ; if so } scanning := true; HLock(handle(p)); pp := p^; FOR i := 1 TO len DO BEGIN IF pp^[i] = chr(13) THEN pp^[i] := ';'; scanning := scanning and (pp^[i] <> ';'); END; IF scanning THEN FOR i := 1 TO len DO IF pp^[i] = delim THEN pp^[i] := ';'; HUnlock(handle(p)); { Extend p by one character if we need to add a ; } { Remember that we have a c format string } SetHandleSize(Handle(p), GetHandleSize(Handle(p))+1); Bomb(MemError); HLock(handle(p)); pp := p^; IF pp^[len] <> ';' THEN BEGIN len := len + 1; { Move the zero back one character } pp^[len+1] := pp^[len]; pp^[len] := ';'; END; IF pp^[1] in [delim,';'] THEN start := 2 ELSE start := 1; Menu[0] := NewMenu(MenuID, ''); IF Menu[0] = NIL THEN BEGIN paramPtr^.returnValue := PasToZero(paramPtr, 'Error: Main Menu Memory Error!'); Exit(HPopupMenu); END; MaxMenu := 0; { Create Main MenuItems } pp := p^; scanning := true; hasSubMenus := False; j := start; FOR i := start TO len DO BEGIN IF scanning THEN IF pp^[i] in [delim,';'] THEN BEGIN MenuItems := myCopy(p, j, i-j); IF pp^[i] = delim THEN BEGIN scanning := false; IF not (pp^[i+1] in [delim,';']) THEN BEGIN hasSubMenus := True; MenuItems := Concat(MenuItems, '/-'); MenuItems[Length(MenuItems)] := chr(hMenuCmd); END; END; IF (menuItems[1] = '®') & (Length(MenuItems) = 5) THEN AddResMenu(Menu[0], ResourceType(MenuItems)) ELSE IF SmallIcon(MenuItems, theIcon) THEN BEGIN AppendMenu(Menu[0], MenuItems); SetItemCmd(Menu[0], CountMItems(Menu[0]), chr(kSmallIconCmd)); SetItemIcon(Menu[0], CountMItems(Menu[0]), Ord(theIcon)); END ELSE DependMenu(Menu[0], MenuItems) END; IF pp^[i] = ';' THEN BEGIN j := i + 1; scanning := true END END; InsertMenu(Menu[0], -1); IF hasSubMenus THEN BEGIN { Create SubMenus } scanning := true; enabled := false; j := 0; FOR i := start TO len DO BEGIN IF pp^[i] in [';',delim] THEN BEGIN IF scanning THEN BEGIN ItemCount := ItemCount + 1; IF pp^[i] = delim THEN BEGIN { Add submenu to main menu } menuCount := menuCount + 1; IF menuCount > MaxMenus THEN BEGIN TidyUp; paramPtr^.returnValue := PasToZero(paramPtr, 'Error: Too many menu items'); Exit(HPopupMenu); END; MaxMenu := MenuId + menuCount; SetItemMark(Menu[0], ItemCount, Chr(MaxMenu)); Menu[menuCount] := NewMenu(MaxMenu, ''); IF Menu[menuCount] = NIL THEN BEGIN TidyUp; paramPtr^.returnValue := PasToZero(paramPtr, 'Error: SubMenu Error'); Exit(HPopupMenu); END; enabled := false; END; END ELSE BEGIN IF j <> i THEN BEGIN MenuItems := myCopy(p, j, i-j); IF (menuItems[1] = '®') & (Length(MenuItems) = 5) THEN AddResMenu(Menu[menuCount], ResourceType(MenuItems)) ELSE IF SmallIcon(MenuItems, theIcon) THEN BEGIN AppendMenu(Menu[menuCount], MenuItems); SetItemCmd(Menu[menuCount], CountMItems(Menu[menuCount]), chr(kSmallIconCmd)); SetItemIcon(Menu[menuCount], CountMItems(Menu[menuCount]), Ord(theIcon)); END ELSE DependMenu(Menu[menuCount], MenuItems); enabled := true; END; IF pp^[i] = ';' THEN IF enabled THEN InsertMenu(Menu[menuCount], -1) ELSE BEGIN SetItemMark(Menu[0], ItemCount, chr(noMark)); DeleteMenu(MaxMenu); DisposeMenu(Menu[menuCount]); Menu[menuCount] := nil; menuCount := menuCount - 1; END; END; j := i + 1; scanning := pp^[i] = ';'; END END; END; HUnlock(handle(p)); DisposeHandle(Handle(p)); END; { StringMenu } PROCEDURE ResourceMenu; PROCEDURE ScanMenus (m : MenuHandle); VAR i, j : Integer; c : Char; BEGIN i := 1; WHILE i <= CountMItems(m) DO BEGIN GetItem(m, i, menuItems); IF (menuItems[1] = '®') & (Length(menuItems) = 5) THEN BEGIN DelMenuItem(m, i); InsertResMenu(m, ResourceType(menuItems), i-1); END ELSE BEGIN GetItemCmd(m, i, c); IF c = chr(hMenuCmd) THEN BEGIN ItemCount := ItemCount + 1; GetItemMark(m, i, c); menuCount := menuCount + 1; j := menuCount; Menu[j] := GetMenu(Ord(c)); IF Menu[j] = NIL THEN BEGIN TidyUp; paramPtr^.returnValue := PasToZero(paramPtr, 'Error: Submenu resource not found'); Exit(HPopupMenu); END; ScanMenus(Menu[j]); InsertMenu(Menu[j], -1); END; END; i := i + 1; END; END; { ScanMenus } BEGIN { ResourceMenu } Menu[0] := GetMenu(ParamToNum(paramPtr^.params[1])); IF Menu[0] = NIL THEN BEGIN TidyUp; paramPtr^.returnValue := PasToZero(paramPtr, 'Error: Invalid Menu Number'); Exit(HPopupMenu); END; InsertMenu(Menu[0], -1); ScanMenus(Menu[0]); END; { ResourceMenu } FUNCTION Numeric (t : Str255) : Boolean; VAR i : Integer; b : Boolean; BEGIN b := True; FOR i := 1 to Length(t) DO b := b & (t[i] IN [' ',' ','+','-','0','1','2','3','4','5','6','7','8','9']); Numeric := b; END; { Numeric } FUNCTION GetItemDelimiter : Char; TYPE Chars = PACKED ARRAY [1..2] OF Char; CharPtr = ^Chars; CharHandle = ^CharPtr; VAR h : Handle; BEGIN h := EvalExpr(paramPtr, 'the itemDelimiter'); IF (h <> NIL) & (StringLength(paramPtr, h^) = 1) THEN GetItemDelimiter := CharHandle(h)^^[1] ELSE GetItemDelimiter := ','; IF h <> NIL THEN DisposeHandle(h); END; { GetItemDelimiter } PROCEDURE StripNulls (VAR t : Str255); VAR i, j : Integer; BEGIN i := 1; WHILE i <= Length(t) DO IF t[i] = Chr(0) THEN BEGIN FOR j := i+1 TO Length(t) DO t[j-1] := t[j]; t[0] := Chr(Ord(t[0])-1); END ELSE i := i + 1; END; { StripNulls } BEGIN { HPopUpMenu }HLock(paramPtr^.Params[1]);WITH paramPtr^ DOIF (paramCount = 1) THEN BEGIN ZeroToPas(paramPtr, params[1]^, menuItems); IF menuItems = '!' THEN returnValue := PasToZero(paramPtr, 'HPopupMenu 3.1.3 Copyright 1989-93 by Jon Pugh (408) 862-7094 jpugh@apple.com Applelink: JONPUGH') ELSE returnValue := PasToZero(ParamPtr, 'Usage: HPopupMenu({ menu items | resource id }, item, h, v [,font, size])') ENDELSE IF (paramCount < 4) OR (paramCount > 6) THEN returnValue := PasToZero(ParamPtr, 'Usage: HPopupMenu({ menu items | resource id }, item, h, v [,font, size])')ELSE IF not button or (StringLength(ParamPtr, Params[1]^) = 0) THEN returnValue := PasToZero(ParamPtr, '')ELSE BEGIN SendCardMessage(paramPtr, Concat('set cursor to watch')); CheckedItem := ParamToNum(params[2]); { Get Menu Position } pt.v := ParamToNum(params[3]); pt.h := ParamToNum(params[4]); localToGlobal(pt); { Get Font Info } IF params[5] <> NIL THEN BEGIN ZeroToPas(paramPtr, params[5]^, theFontName); GetFNum(theFontName, theFont); IF theFont = 0 THEN BEGIN GetFontName(0, MenuItems); IF NOT EqualString(theFontName, MenuItems, False, False) THEN theFontName := ''; END END ELSE theFontName := ''; IF (params[6] <> NIL) AND (theFontName <> '') THEN theSize := ParamToNum(params[6]) ELSE theSize := 0; delim := GetItemDelimiter; ItemCount := 0; menuCount := 0; ZeroToPas(paramPtr, params[1]^, menuItems); IF Numeric(menuItems) THEN ResourceMenu ELSE IF (menuItems[1] = '®') & (Length(menuItems) = 5) THEN BEGIN Menu[0] := NewMenu(MenuID, ''); IF Menu[0] = NIL THEN BEGIN returnValue := PasToZero(paramPtr, 'Error: Memory error on resource menu'); Exit(HPopupMenu); END; AddResMenu(Menu[0], ResourceType(menuItems)); InsertMenu(Menu[0], -1); END ELSE StringMenu; IF checkedItem > 0 THEN CheckItem(Menu[0], CheckedItem, true); { Get Menu Selection } IF button THEN BEGIN { Set the Font } IF theFontName <> '' THEN BEGIN { To cover for µSoft and Claris MDEFs } WinMgr := Pointer(WMgrPort); oldSysSize := WinMgr^^.txSize; oldSysFont := WinMgr^^.txFont; WinMgr^^.txSize := 0; WinMgr^^.txFont := 0; aWord := Pointer(Rom85); IF aWord^ <> $7FFF THEN BEGIN CWinMgr := Pointer(WMgrCPort); oldSysCSize := CWinMgr^^.txSize; oldSysCFont := CWinMgr^^.txFont; CWinMgr^^.txSize := 0; CWinMgr^^.txFont := 0; END; { The real trick } aWord := Pointer(SysFontFamAddr); oldFont := aWord^; aWord^ := theFont; aWord := Pointer(SysFontSizeAddr); oldSize := aWord^; aWord^ := theSize; aLongInt := Pointer(LastSpExtraAddr); aLongInt^ := -1; END; SendCardMessage(paramPtr, Concat('set cursor to arrow')); SelectedItem := PopUpMenuSelect(Menu[0], pt.v, pt.h, abs(CheckedItem)); IF HiWord(SelectedItem) = 0 THEN BEGIN { Check for items that aren't returned } aLongInt := Pointer(MenuDisableAddr); SelectedItem := aLongInt^; END; { Reset the Font and Size } IF theFontName <> '' THEN BEGIN { Reset global MDEF crap } WinMgr^^.txSize := oldSysSize; WinMgr^^.txFont := oldSysFont; aWord := Pointer(Rom85); IF aWord^ <> $7FFF THEN BEGIN CWinMgr^^.txSize := oldSysCSize; CWinMgr^^.txFont := oldSysCFont; END; { Reset things } aWord := Pointer(SysFontFamAddr); aWord^ := oldFont; aWord := Pointer(SysFontSizeAddr); aWord^ := oldSize; aLongInt := Pointer(LastSpExtraAddr); aLongInt^ := -1; END; END ELSE SelectedItem := 0; h := HiWord(SelectedItem); l := LoWord(SelectedItem); { Convert numbers to words } IF l = 0 THEN BEGIN { Nothing selected } AllItems := ''; MenuItems := ''; theFontName := ''; enabled := False; END ELSE IF h = Menu[0]^^.menuID THEN BEGIN { Chose main menu } GetItem(Menu[0], l, AllItems); StripNulls(AllItems); MenuItems := ''; enabled := BTsT(Menu[0]^^.enableFlags, l) OR (l > 31); theFontName := Concat(AllItems, delim, '', delim, myNumToStr(l), delim, '0'); END ELSE BEGIN { Find the leaf node menu item l of menu id h } FOR j := menuCount DOWNTO 0 DO BEGIN IF (Menu[j] <> NIL) & (Menu[j]^^.menuID = h) THEN BEGIN enabled := BTsT(Menu[j]^^.enableFlags, l) OR (l > 31); GetItem(Menu[j], l, allItems); StripNulls(allItems); theFontName := myNumToStr(l); Leave; END; END; IF enabled THEN BEGIN REPEAT { Find menu item which has h as a subMenu } { Set l to menu item number and h to menu id } scanning := True; FOR j := 0 TO menuCount DO IF Menu[j] <> NIL THEN BEGIN FOR i := 1 TO CountMItems(Menu[j]) DO BEGIN GetItemCmd(Menu[j], i, c); IF c = chr(hMenuCmd) THEN BEGIN GetItemMark(Menu[j], i, c); IF Ord(c) = h THEN BEGIN GetItem(Menu[j], i, menuItems); StripNulls(menuItems); l := i; h := Menu[j]^^.menuID; scanning := False; Leave; END; END; END; IF NOT scanning THEN Leave; END; { h & l have changed, now save menu text } IF length(menuItems) + length(allItems) + 1 < 256 THEN allItems := Concat(menuItems, delim, allItems); theFontName := Concat(myNumToStr(l), delim, theFontName); UNTIL menu[0]^^.menuID = h; IF length(allItems) + length(theFontName) + 1 < 256 THEN theFontName := Concat(allItems, delim, theFontName); END ELSE theFontName := ''; END; TidyUp; { Return the words and numbers } IF enabled THEN returnValue := PasToZero(ParamPtr, theFontName) ELSE returnValue := NIL; END;HLock(paramPtr^.Params[1]);END; { HPopUpMenu }END. { HPopUp Unit }</text>
</content>
<name></name>
<script>on closeCardif visible of card field "Code" then hide card field "Code"pass closeCardend closeCard</script>